<?php

namespace App\Service\Cruise\Check;

use App\Http\Resources\CruiseCheck\CruiseCheckSelfDetailListResource;
use App\Http\Resources\CruiseCheck\CruiseCheckSelfDetailResource;
use App\Http\Resources\CruiseCheck\CruiseCheckSelfTaskListResource;
use App\Http\Resources\CruiseCheck\CruiseCheckSelfTaskResource;
use App\Http\Resources\CruiseCheck\Merchant\ShopSelfCheckDetailListResource;
use App\Http\Resources\CruiseCheck\Merchant\ShopSelfCheckListResource;
use App\Http\Resources\CruiseCheck\SupplierTaskDetailResource;
use App\Http\Resources\CruiseCheck\SupplierTaskGroupPreviewResource;
use App\Http\Resources\CruiseCheck\SupplierTaskPreviewResource;
use App\Jobs\Cruise\CruiseCheckSelfTaskInsertOrUpdateJob;
use App\Library\Rms\RmsUserApi;
use App\Models\BaseModel;
use App\Models\Cruise\CruiseCheckCompanyModel;
use App\Models\Cruise\CruiseCheckDetailModel;
use App\Models\Cruise\CruiseCheckSelfDetailModel;
use App\Models\Cruise\CruiseCheckSelfTaskCompanyMappingModel;
use App\Models\Cruise\CruiseCheckSelfTaskModel;
use App\Models\Cruise\CruiseCheckTaskModel;
use App\Models\Cruise\CruiseOrderInputModel;
use App\Models\Cruise\CruiseOrderModel;
use App\Models\Cruise\CruiseOrderProcessModel;
use App\Models\Cruise\CruiseTaskOrderMappingModel;
use App\Models\Cruise\CruiseTemplateModel;
use App\Remote\Rms\RmsUserRemote;
use App\Service\BaseService;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;

class CruiseCheckSelfTaskService extends BaseService
{
    /**
     * @param object $params
     * @throws ValidationException
     */
    public static function insert(object $params)
    {
        $cruiseTemplateModel = CruiseTemplateModel::query()->where('id', $params->templateId)->first();
        if (!$cruiseTemplateModel || !in_array($cruiseTemplateModel->type, [CruiseTemplateModel::TYPE_5, CruiseTemplateModel::TYPE_8])) {
            BaseService::throwErr("模板类型错误");
        }

        try {
            DB::beginTransaction();

            $cruiseCheckSelfTaskId = CruiseCheckSelfTaskModel::query()->insertGetId(array_merge(
                collect((array)$params)->except(['cruiseCheckCompanyIds', 'shopIds'])->toArray(),
                [
                    'templateType' => $cruiseTemplateModel->type,
                    'sysTemplate'  => $cruiseTemplateModel->sysTemplate,
                    "status"       => CruiseCheckSelfTaskModel::STATUS_ON,
                    "createdAt"    => time(),
                    "updatedAt"    => time(),
                    "updatedByUid" => request()->user()->id,
                    "createdByUid" => request()->user()->id
                ]
            ));

            $mappings = null;
            if ($cruiseTemplateModel->type == CruiseTemplateModel::TYPE_5) {
                $mappings = collect($params->cruiseCheckCompanyIds)->map(function ($checkCompanyId) use (
                    $cruiseCheckSelfTaskId
                ) {
                    return [
                        'shopId'               => 0,
                        "cruiseCheckCompanyId" => $checkCompanyId,
                        "taskId"               => $cruiseCheckSelfTaskId,
                        "createdAt"            => time(),
                        "createdByUid"         => request()->user()->id,
                        "updatedAt"            => time()
                    ];
                })->values()->toArray();
            } else {
                if($params->shopScope == CruiseCheckSelfTaskModel::SHOP_SCOPE_PART){
                    $mappings = collect($params->shopIds)->map(function ($shopId) use ($cruiseCheckSelfTaskId) {
                        return [
                            'shopId'               => $shopId,
                            "cruiseCheckCompanyId" => 0,
                            "taskId"               => $cruiseCheckSelfTaskId,
                            "createdAt"            => time(),
                            "createdByUid"         => request()->user()->id,
                            "updatedAt"            => time()
                        ];
                    })->values()->toArray();
                }
            }

            if(!empty($mappings)){
                CruiseCheckSelfTaskCompanyMappingModel::query()->insert($mappings);
            }


            DB::commit();

            // todo 新增自检任务队列生成任务详细数据
            dispatch(
                new CruiseCheckSelfTaskInsertOrUpdateJob(
                    CruiseCheckSelfTaskInsertOrUpdateJob::INSERT,
                    $cruiseCheckSelfTaskId)
            )->onQueue(CruiseCheckSelfTaskInsertOrUpdateJob::$QUEUE);

        } catch (\Exception $exception) {
            DB::rollBack();
            handleException($exception, null, null, "添加自检任务失败");
        }
    }

    /**
     * @param object $params
     * @throws ValidationException
     */
    public static function update(object $params)
    {
        $cruiseTemplateModel = CruiseTemplateModel::query()->where('id', $params->templateId)->first();
        if (!$cruiseTemplateModel || !in_array($cruiseTemplateModel->type, [CruiseTemplateModel::TYPE_5, CruiseTemplateModel::TYPE_8])) {
            BaseService::throwErr("模板类型错误");
        }

        try {
            DB::beginTransaction();
            CruiseCheckSelfTaskModel::query()->where("id", $params->id)->update(array_merge(
                collect((array)$params)->except(['shopIds', "cruiseCheckCompanyIds"])->toArray(),
                [
                    'templateType' => $cruiseTemplateModel->type,
                    'sysTemplate'  => $cruiseTemplateModel->sysTemplate,
                    "updatedAt"    => time(),
                    "updatedByUid" => request()->user()->id
                ]
            ));

            CruiseCheckSelfTaskCompanyMappingModel::query()->where("taskId", $params->id)->delete();
            $cruiseCheckSelfTaskId = $params->id;

            $mappings = null;
            if ($cruiseTemplateModel->type == CruiseTemplateModel::TYPE_5) {
                $mappings = collect($params->cruiseCheckCompanyIds)->map(function ($checkCompanyId) use (
                    $cruiseCheckSelfTaskId
                ) {
                    return [
                        'shopId'               => 0,
                        "cruiseCheckCompanyId" => $checkCompanyId,
                        "taskId"               => $cruiseCheckSelfTaskId,
                        "createdAt"            => time(),
                        "createdByUid"         => request()->user()->id,
                        "updatedAt"            => time()
                    ];
                })->values()->toArray();
            } else {
                if($params->shopScope == CruiseCheckSelfTaskModel::SHOP_SCOPE_PART){
                    $mappings = collect($params->shopIds)->map(function ($shopId) use ($cruiseCheckSelfTaskId) {
                        return [
                            'shopId'               => $shopId,
                            "cruiseCheckCompanyId" => 0,
                            "taskId"               => $cruiseCheckSelfTaskId,
                            "createdAt"            => time(),
                            "createdByUid"         => request()->user()->id,
                            "updatedAt"            => time()
                        ];
                    })->values()->toArray();
                }
            }

            if(!empty($mappings)){
                CruiseCheckSelfTaskCompanyMappingModel::query()->insert($mappings);
            }

            DB::commit();

            // todo 编辑自检任务队列生成任务详细数据
            dispatch(
                new CruiseCheckSelfTaskInsertOrUpdateJob(
                    CruiseCheckSelfTaskInsertOrUpdateJob::UPDATE,
                    $cruiseCheckSelfTaskId)
            )->onQueue(CruiseCheckSelfTaskInsertOrUpdateJob::$QUEUE);

        } catch (\Exception $exception) {
            DB::rollBack();
            handleException($exception, null, null, "更新自检任务失败");
        }
    }

    /**
     * @param object $params
     * @throws ValidationException
     */
    public static function del(object $params)
    {
        try {
            CruiseCheckSelfTaskModel::query()->where("id", $params->id)->update([
                "isDeleted"    => 1,
                "updatedAt"    => time(),
                "updatedByUid" => request()->user()->id
            ]);
        } catch (\Exception $exception) {
            handleException($exception, null, null, "删除自检任务失败");
        }
    }

    /**
     * @param object $params
     * @throws ValidationException
     */
    public static function status(object $params)
    {
        try {
            CruiseCheckSelfTaskModel::query()->where("id", $params->id)->update([
                "status"       => $params->status,
                "updatedAt"    => time(),
                "updatedByUid" => request()->user()->id
            ]);

            if ($params->status) {
                // todo 编辑自检任务队列生成任务详细数据
                dispatch(
                    new CruiseCheckSelfTaskInsertOrUpdateJob(
                        CruiseCheckSelfTaskInsertOrUpdateJob::UPDATE,
                        $params->id)
                )->onQueue(CruiseCheckSelfTaskInsertOrUpdateJob::$QUEUE);
            }
        } catch (\Exception $exception) {
            handleException($exception, null, null,
                CruiseCheckSelfTaskModel::STATUS_TEXT[$params->status] . "自检任务失败");
        }
    }

    /**
     * @param object $params
     * @return array|void
     * @throws ValidationException
     */
    public static function detail(object $params)
    {
        try {
            $cruiseCheckSelfTaskModel = CruiseCheckSelfTaskModel::query()
                                                                ->with([
                                                                    "cruiseTemplateRel",
                                                                    "cruiseCheckSelfTaskCompanyMappingsRel.cruiseCheckCompanyRel.fsCompanyRel"
                                                                ])
                                                                ->where("id", $params->id)
                                                                ->first();

            return [
                "detail" => CruiseCheckSelfTaskResource::collection([$cruiseCheckSelfTaskModel])
                                                       ->getIterator()
                                                       ->current()
            ];
        } catch (\Exception $exception) {
            handleException($exception, null, null, "查看自检任务详情失败");
        }
    }

    /**
     * @param int $pageNum
     * @param int $pageSize
     * @param string $name
     * @param int $cruiseCheckCompanyId
     * @return array|void
     * @throws ValidationException
     */
    public static function index(
        int $pageNum,
        int $pageSize,
        string $name,
        int $cruiseCheckCompanyId,
        int $templateType,
        array $shopIds = []
    ) {
        try {
            $paginate = CruiseCheckSelfTaskModel::query()
                                                ->with([
                                                    "cruiseTemplateRel",
                                                    "cruiseCheckSelfTaskCompanyMappingsRel.cruiseCheckCompanyRel.fsCompanyRel",
                                                    "cruiseCheckSelfTaskCompanyMappingsRel.cruiseCheckShopRel",
                                                ])
                                                ->where('templateType', $templateType)
                                                ->when(strlen($name), function ($query) use ($name) {
                                                    $query->where("name", "like", "%{$name}%");
                                                })
                                                ->when($cruiseCheckCompanyId > 0,
                                                    function ($query) use ($cruiseCheckCompanyId) {
                                                        $query->whereHas('cruiseCheckSelfTaskCompanyMappingsRel',
                                                            function ($query) use ($cruiseCheckCompanyId
                                                            ) {
                                                                $query->where('cruiseCheckCompanyId',
                                                                    $cruiseCheckCompanyId);
                                                            });
                                                    })
                                                ->when($shopIds, function ($query) use ($shopIds) {

                                                    $child = CruiseCheckSelfTaskCompanyMappingModel::query()
                                                                                                   ->whereIn('shopId',
                                                                                                       $shopIds)
                                                                                                   ->select('taskId');

                                                    $query->where(function ($q) use ($child) {
                                                        $q->whereRaw("id in (" . BaseModel::toSqlWithParam($child) . ')')
                                                          ->orWhere('shopScope',
                                                              CruiseCheckSelfTaskModel::SHOP_SCOPE_ALL);
                                                    });
                                                })
                                                ->orderByDesc("createdAt")
                                                ->orderBy("status", "desc")
                                                ->orderBy("taskEndTime", "asc")
                                                ->paginate($pageSize, ['*'], 'pageNum', $pageNum);


            $updatedUids                                        = collect($paginate->items())->pluck("updatedByUid")
                                                                                             ->unique()->filter()
                                                                                             ->toArray();
            CruiseCheckSelfTaskListResource::$rmsUserCollection = collect($updatedUids ? RmsUserRemote::getRmsUserByIds($updatedUids) : [])->keyBy("id");

            return [
                "count"         => $paginate->total(),
                "list"          => CruiseCheckSelfTaskListResource::collection($paginate->items()),
                "ruleSelection" => enumToSelection(CruiseCheckSelfTaskModel::RULE_TEXT),
                "pageNum"       => $pageNum,
                "pageSize"      => $pageSize
            ];
        } catch (\Exception $exception) {
            handleException($exception, null, null, "查看自检任务列表失败");
        }
    }

    /**
     * @param object $params
     * @return array|void
     * @throws ValidationException
     */
    public static function finishCondition(object $params)
    {
        try {

            $cruiseCheckSelfTaskModel = CruiseCheckSelfTaskModel::query()
                                                                ->with([
//                                                                    "cruiseCheckSelfDetailRel"              => function (
//                                                                        $query
//                                                                    ) {
//                                                                        $query->with([
//                                                                            "cruiseCheckDetailsRel",
//                                                                            "cruiseCheckCompanyRel.fsCompanyRel"
//                                                                        ]);
//                                                                    },
                                                                    "cruiseTemplateRel",
                                                                    "cruiseCheckSelfTaskCompanyMappingsRel" => function (
                                                                        $query
                                                                    ) use ($params) {
                                                                        $query->with([
                                                                            "cruiseCheckCompanyRel.fsCompanyRel",
                                                                            "cruiseCheckSelfDetailRel" => function (
                                                                                $query
                                                                            ) use ($params) {
                                                                                $query->with("cruiseCheckDetailsRel")
                                                                                      ->where("taskId", $params->id);
                                                                            }
                                                                        ]);
                                                                    },
                                                                    "cruiseCheckSelfTaskCompanyMappingsRel.cruiseCheckShopRel",
                                                                ])
                                                                ->where("id", $params->id)
                                                                ->first();

            return [
                "detail" => CruiseCheckSelfDetailResource::collection([$cruiseCheckSelfTaskModel])->offsetGet(0)
            ];
        } catch (\Exception $exception) {
            handleException($exception, null, null, "查看自检任务完成情况失败");
        }
    }

    /**
     * 工厂自检首页
     *
     * @return array|void
     * @throws ValidationException
     * @throws GuzzleException
     */
    public static function supplierTaskGroupPreview()
    {

        try {
            $cruiseCheckCompanyModelGroup = CruiseCheckCompanyModel::query()
                                                                   ->where("status", CruiseCheckCompanyModel::STATUS_ON)
                                                                   ->when(!self::hasSuperAuth(), function ($query) {
                                                                       $query->where("companyManagerId",
                                                                           request()->user()->id);
                                                                   })
                                                                   ->whereHas("cruiseCheckSelfTaskCompanyMappingsRel.cruiseCheckSelfTaskRel",
                                                                       function ($query) {
                                                                           $query->where("status",
                                                                               CruiseCheckSelfTaskModel::STATUS_ON)
                                                                                 ->where("isDeleted", 0);
                                                                       })
                                                                   ->with([
                                                                       "fsCompanyRel",
                                                                       "cruiseCheckSelfDetailRel"              => function (
                                                                           $query
                                                                       ) {
                                                                           $query->whereHas("cruiseCheckSelfTaskRel",
                                                                               function ($query) {
                                                                                   $query->where("status",
                                                                                       CruiseCheckSelfTaskModel::STATUS_ON)
                                                                                         ->where("isDeleted", 0);
                                                                               });
                                                                       },
                                                                       "cruiseCheckSelfTaskCompanyMappingsRel" => function (
                                                                           $query
                                                                       ) {
                                                                           $query->with("cruiseCheckSelfTaskRel")
                                                                                 ->whereHas("cruiseCheckSelfTaskRel",
                                                                                     function ($query) {
                                                                                         $query
                                                                                             ->where("status",
                                                                                                 CruiseCheckSelfTaskModel::STATUS_ON)
                                                                                             ->where("taskStartTime",
                                                                                                 "<=", time())
                                                                                             ->where("taskEndTime", ">",
                                                                                                 time() - 24 * 60 * 60)
                                                                                             ->where("isDeleted", 0);
                                                                                     });
                                                                       }
                                                                   ])->get();

            $rmsUids = [];
            $cruiseCheckCompanyModelGroup->map(
                function (CruiseCheckCompanyModel $cruiseCheckCompanyModel) use (&$rmsUids) {
                    array_push(
                        $rmsUids,
                        $cruiseCheckCompanyModel->companyManagerId,
                        $cruiseCheckCompanyModel->kfManagerId
                    );
                }
            );

            SupplierTaskGroupPreviewResource::$rmsUserCollection = $rmsUids ? collect(RmsUserRemote::getRmsUserByIds(array_unique($rmsUids)))->keyBy("id") : collect([]);

            return [
                "list" => SupplierTaskGroupPreviewResource::collection($cruiseCheckCompanyModelGroup)
            ];
        } catch (\Exception $exception) {
            handleException($exception, null, null, "查看工厂自检首页失败");
        }
    }

    /**
     * @param object $params
     * @return array|void
     * @throws ValidationException
     */
    public static function supplierTaskPreview(object $params)
    {
        try {
            $cruiseCheckCompanyModelGroup = CruiseCheckCompanyModel::query()
                                                                   ->where("status", CruiseCheckCompanyModel::STATUS_ON)
                                                                   ->where("id", $params->cruiseCheckCompanyId)
                                                                   ->whereHas("cruiseCheckSelfTaskCompanyMappingsRel.cruiseCheckSelfTaskRel",
                                                                       function ($query) {
                                                                           $query->where("isDeleted", 0);
                                                                       })
                                                                   ->with([
                                                                       "fsCompanyRel",
                                                                       "cruiseCheckSelfDetailRel"              => function (
                                                                           $query
                                                                       ) {
                                                                           $query->whereHas("cruiseCheckSelfTaskRel",
                                                                               function ($query) {
                                                                                   $query->where("status",
                                                                                       CruiseCheckSelfTaskModel::STATUS_ON)
                                                                                         ->where("isDeleted", 0);
                                                                               });
                                                                       },
                                                                       "cruiseCheckSelfTaskCompanyMappingsRel" => function (
                                                                           $query
                                                                       ) {
                                                                           $query->with("cruiseCheckSelfTaskRel")
                                                                                 ->whereHas("cruiseCheckSelfTaskRel",
                                                                                     function ($query) {
                                                                                         $query
                                                                                             ->where("status",
                                                                                                 CruiseCheckSelfTaskModel::STATUS_ON)
//                                                                                             ->where("taskStartTime",
//                                                                                                 "<=", time())
//                                                                                             ->where("taskEndTime", ">",
//                                                                                                 time() - 24 * 60 * 60)
                                                                                             ->where("isDeleted", 0);
                                                                                     });
                                                                       }
                                                                   ])->get();

            return [
                "isSuper"          => self::hasSuperAuth(),
                "companyManagerId" => attributeGet($cruiseCheckCompanyModelGroup, "0.companyManagerId", 0),
                "kfManagerId"      => attributeGet($cruiseCheckCompanyModelGroup, "0.kfManagerId", 0),
                "list"             => SupplierTaskPreviewResource::collection($cruiseCheckCompanyModelGroup)
                                                                 ->offsetGet(0)
            ];
        } catch (\Exception$exception) {
            handleException($exception, null, null, "查看工厂自检列表失败");
        }
    }

    /**
     * @param object $params
     * @throws ValidationException
     */
    public static function todayNotProduce(object $params)
    {
        try {

            collect((array)$params->taskIds)->each(function ($taskId) use ($params) {
                CruiseCheckSelfDetailModel::query()->updateOrInsert(
                    [
                        "taskId"               => $taskId,
                        "cruiseCheckCompanyId" => $params->cruiseCheckCompanyId,
                        "date"                 => date("Ymd", time())
                    ],
                    [
                        "status"    => CruiseCheckSelfDetailModel::STATUS_NOT_PRODUCE,
                        "createdAt" => time(),
                        "updatedAt" => time()
                    ]
                );
            });
        } catch (\Exception $exception) {
            handleException($exception, null, null, "今日任务不生产操作失败");
        }
    }

    /**
     * @param object $params
     * @return \stdClass[]|void
     * @throws GuzzleException
     * @throws ValidationException
     */
    public static function supplierTaskDetail(object $params)
    {
        try {
            $cruiseCheckSelfTaskModel = CruiseCheckSelfTaskModel::query()
                                                                ->where("id", $params->taskId)
                                                                ->with([
                                                                    "cruiseCheckSelfDetailRel" => function ($query) use
                                                                    (
                                                                        $params
                                                                    ) {
                                                                        $query->with([
                                                                            "cruiseCheckDetailsRel.cruiseOrderRel.cruiseOrderProcessRel.examineLogRel",
                                                                            "cruiseCheckCompanyRel.fsCompanyRel"
                                                                        ])->where("cruiseCheckCompanyId",
                                                                            $params->cruiseCheckCompanyId);
                                                                    }
                                                                ])->first();


            $rmsUids = [];
            $cruiseCheckSelfTaskModel->cruiseCheckSelfDetailRel
                ->each(function (CruiseCheckSelfDetailModel $cruiseCheckSelfDetailModel) use (&$rmsUids) {
                    $cruiseOrderModel      = attributeGet($cruiseCheckSelfDetailModel, "cruiseOrderRel", null);
                    $cruiseOrderProcessRel = attributeGet(
                        $cruiseCheckSelfDetailModel,
                        "cruiseOrderRel.cruiseOrderProcessRel",
                        null
                    );

                    if ($cruiseOrderModel && $cruiseOrderProcessRel) {
                        $rmsUids = array_merge(
                            $rmsUids,
                            [
                                $cruiseOrderModel->cretedByUid,
                                $cruiseOrderModel->handlerId,
                                object_get($cruiseOrderModel, "checkTaskDetailRel.dealUid", 0),
                                object_get($cruiseCheckSelfDetailModel, "cruiseCheckCompanyRel.companyManagerId", 0),
                                object_get($cruiseCheckSelfDetailModel, "cruiseCheckCompanyRel.kfManagerId", 0)
                            ],
                            $cruiseOrderModel->cruiseOrderProcessRel ? $cruiseOrderModel->cruiseOrderProcessRel->pluck("createdByUid")
                                                                                                               ->toArray() : []);
                    }

                    $rmsUids = array_merge(
                        $rmsUids,
                        [object_get($cruiseCheckSelfDetailModel, "cruiseCheckDetailsRel.createdByUid", 0)]
                    );
                });

            $rmsUids                                              = array_filter(array_unique($rmsUids));
            $rmsUserCollection                                    = $rmsUids ? collect(RmsUserRemote::getRmsUserByIds(array_unique($rmsUids)))->keyBy("id") : collect([]);
            CruiseCheckSelfDetailListResource::$rmsUserCollection = $rmsUserCollection;

            CruiseCheckSelfDetailListResource::$process = collect(
                self::getOrderProcess(
                    $cruiseCheckSelfTaskModel,
                    $rmsUserCollection
                )
            );

            return [
                "isSuper" => self::hasSuperAuth(),
                "detail"  => $cruiseCheckSelfTaskModel ? SupplierTaskDetailResource::collection([$cruiseCheckSelfTaskModel])
                                                                                   ->offsetGet(0) : new \stdClass()
            ];

        } catch (\Exception $exception) {
            handleException($exception, null, null, "今日任务不生产操作失败");
        }
    }

    /**
     * @param CruiseCheckSelfTaskModel $cruiseCheckSelfTaskModel
     * @param Collection $rmsUserInfo
     * @return mixed
     */
    public static function getOrderProcess(CruiseCheckSelfTaskModel $cruiseCheckSelfTaskModel, Collection $rmsUserInfo)
    {
        return $cruiseCheckSelfTaskModel->cruiseCheckSelfDetailRel
            ->where("status", "<>", CruiseCheckSelfDetailModel::STATUS_NOT_PRODUCE)
            ->map(function (
                CruiseCheckSelfDetailModel $cruiseCheckSelfDetailModel
            ) use (
                $rmsUserInfo,
                $cruiseCheckSelfTaskModel
            ) {
                $cruiseOrderModel      = attributeGet(
                    $cruiseCheckSelfDetailModel,
                    "cruiseCheckDetailsRel.cruiseOrderRel",
                    null
                );
                $cruiseOrderProcessRel = attributeGet(
                    $cruiseCheckSelfDetailModel,
                    "cruiseCheckDetailsRel.cruiseOrderRel.cruiseOrderProcessRel",
                    null
                );
                $step                  = CruiseOrderProcessModel::PROCESS_CREATED;
                $stepStatus            = CruiseOrderProcessModel::STATUS_OK;

                $processList = [];

                if ($cruiseOrderProcessRel) {
                    $processList = $cruiseOrderProcessRel
                        ->map(function (
                            CruiseOrderProcessModel $cruiseOrderProcessModel
                        ) use (
                            $rmsUserInfo,
                            &$step,
                            &$stepStatus
                        ) {
                            $step       = $cruiseOrderProcessModel->step;
                            $stepStatus = $cruiseOrderProcessModel->status;
                            return [
                                'date'       => $cruiseOrderProcessModel->createdAt->format('m-d H:i'),
                                'time'       => $cruiseOrderProcessModel->createdAt->format('Y-m-d H:i:d'),
                                'handler'    => attributeGet(
                                    $rmsUserInfo,
                                    "{$cruiseOrderProcessModel->createdByUid}.username",
                                    "系统"
                                ),
                                'status'     => in_array($cruiseOrderProcessModel->step,
                                    [
                                        CruiseOrderProcessModel::PROCESS_REVIEWED,
                                        CruiseOrderProcessModel::PROCESS_EXT_REVIEWED
                                    ]) ? $cruiseOrderProcessModel->status : CruiseOrderProcessModel::STATUS_OK,
                                'step'       => $cruiseOrderProcessModel->step,
                                'statusText' => in_array($cruiseOrderProcessModel->step,
                                    [
                                        CruiseOrderProcessModel::PROCESS_REVIEWED,
                                        CruiseOrderProcessModel::PROCESS_EXT_REVIEWED
                                    ]) ? (CruiseOrderProcessModel::STATUS_MAPPING[$cruiseOrderProcessModel->status] ?? '-') : (CruiseOrderProcessModel::PROCESS_MAPPING[$cruiseOrderProcessModel->step] ?? '-'),
                                'desc'       => attributeGet($cruiseOrderProcessModel,
                                    "examineLogRel.content", ""),
                            ];
                        })->values()->toArray();
                }

                $getNextStep = function (
                    int $nowStep,
                    int $stepStatus,
                    Collection $rmsUserInfo,
                    CruiseCheckSelfDetailModel $cruiseCheckSelfDetailModel
                ) {
                    $handleUsername         = "-";
                    $companyManagerUsername = attributeGet(
                        $rmsUserInfo,
                        attributeGet($cruiseCheckSelfDetailModel,
                            "cruiseCheckCompanyRel.companyManagerId",
                            0) . ".username",
                        "-"
                    );
                    $kfManagerUsername      = attributeGet(
                        $rmsUserInfo,
                        attributeGet($cruiseCheckSelfDetailModel,
                            "cruiseCheckCompanyRel.kfManagerId",
                            0) . ".username",
                        "-"
                    );

                    switch ($nowStep) {
                        case CruiseOrderProcessModel::PROCESS_CREATED:
                            $nextStep       = CruiseOrderProcessModel::PROCESS_SUBMITTED;
                            $handleUsername = $companyManagerUsername;
                            break;
                        case CruiseOrderProcessModel::PROCESS_SUBMITTED:
                        case CruiseOrderProcessModel::PROCESS_MODIFIED:
                            $nextStep       = CruiseOrderProcessModel::PROCESS_REVIEWED;
                            $handleUsername = $kfManagerUsername;
                            break;
                        case CruiseOrderProcessModel::PROCESS_REVIEWED:
                            if ($stepStatus == CruiseOrderProcessModel::STATUS_OFF) {
                                $nextStep       = CruiseOrderProcessModel::PROCESS_MODIFIED;
                                $handleUsername = $companyManagerUsername;
                            } else {
                                $nextStep = CruiseOrderProcessModel::PROCESS_COMPLETED;
                            }
                            break;
                        default:
                            $nextStep = CruiseOrderProcessModel::PROCESS_COMPLETED;
                    }
                    return [$nextStep, $handleUsername];
                };

                if (!in_array($step,
                        [
                            CruiseOrderProcessModel::PROCESS_COMPLETED,
                            CruiseOrderProcessModel::PROCESS_CANCEL
                        ]) && $cruiseOrderModel
                ) {

//                    if (time() > strtotime(formatDateYmd(time()) . " " . $cruiseCheckSelfTaskModel->executeEndHis)) {
//                        $nextStep       = CruiseOrderProcessModel::PROCESS_CANCEL;
//                        $handleUsername = "系统";
//                    } else {
                    list($nextStep, $handleUsername) = $getNextStep(
                        $step,
                        $stepStatus,
                        $rmsUserInfo,
                        $cruiseCheckSelfDetailModel
                    );
//                    }

                    $processList[] = [
                        'date'       => '-',
                        'handler'    => $handleUsername,
                        'status'     => CruiseOrderProcessModel::STATUS_GREY,
                        'step'       => $nextStep,
                        'statusText' => CruiseOrderProcessModel::PROCESS_PUSH_MAPPING[$nextStep] ?? '-',
                        'desc'       => '',
                    ];
                }

                return [
                    "orderId" => attributeGet($cruiseOrderModel,
                        "id", null),
                    "process" => $processList
                ];
            })->values()->toArray();
    }

    /**
     * @return bool
     */
    public static function hasSuperAuth(): bool
    {
        return in_array(strtolower("b.cruise.selfCheck.listAll"), request()->user()->permissions);
    }

    /**
     * 门店自检菜单列表
     *
     * @param object $params
     * @return array
     */
    public static function shopSelfCheckTaskList(object $params): array
    {
        $paginate = CruiseCheckSelfTaskModel::query()
                                            ->withCount("cruiseCheckSelfDetailRel as totalCount")
                                            ->withCount([
                                                "cruiseCheckSelfDetailRel as totalCount"=> function($query)use($params){
                                                    $query->where("shopId", $params->shopId);
                                                },
                                                    "cruiseCheckSelfDetailRel as finishCount"  => function ($query)use($params) {
                                                        $query->where("status",
                                                            CruiseCheckSelfDetailModel::STATUS_FINISH)->where("shopId", $params->shopId);
                                                    },
                                                    "cruiseCheckSelfDetailRel as invalidCount" => function ($query)use($params) {
                                                        $query->where("status",
                                                            CruiseCheckSelfDetailModel::STATUS_NOT_PRODUCE)->where("shopId", $params->shopId);
                                                    }
                                                ]
                                            )
                                            ->where("templateType", CruiseTemplateModel::TYPE_8)
                                            ->where(function ($query) use ($params) {
                                                $query->whereHas(
                                                    "cruiseCheckSelfTaskCompanyMappingsRel",
                                                    function ($query) use ($params) {
                                                        $query->where("shopId", $params->shopId);
                                                    })->orWhere("shopScope", CruiseCheckSelfTaskModel::SHOP_SCOPE_ALL);
                                            })
                                            ->where(function ($query) use ($params) {
                                                switch ($params->state) {
                                                    case CruiseCheckSelfTaskModel::TYPE_8_STATE_0:
                                                        return $query->where("status", CruiseCheckSelfTaskModel::STATUS_ON);
                                                    case CruiseCheckSelfTaskModel::TYPE_8_STATE_2:
                                                        return $query->where("taskStartTime", ">", time())->where("status", CruiseCheckSelfTaskModel::STATUS_ON);
                                                    case CruiseCheckSelfTaskModel::TYPE_8_STATE_1:
                                                        return $query->where("taskStartTime", "<=", time())
                                                                     ->where("taskEndTime", ">=", time())->where("status", CruiseCheckSelfTaskModel::STATUS_ON);
                                                    case CruiseCheckSelfTaskModel::TYPE_8_STATE_3:
                                                        return $query->where(function($query){
                                                            $query->where("taskEndTime", "<", time())->orWhere("status", CruiseCheckSelfTaskModel::STATUS_OFF);
                                                        });
                                                }
                                            })
                                            ->orderByDesc("id")
                                            ->paginate($params->pageSize, ['*'], 'pageNum', $params->pageNum);

        return [
            "list"     => ShopSelfCheckListResource::collection($paginate->items()),
            "count"    => $paginate->total(),
            "pageNum"  => $params->pageNum,
            "pageSize" => $params->pageSize,
        ];
    }

    /**
     * @param object $params
     * @return array
     */
    public static function shopSelfCheckTaskDetail(object $params): array
    {
        $selfCheckModel = ShopSelfCheckDetailListResource::$checkSelfTaskModel = CruiseCheckSelfTaskModel::query()
                                                                                                         ->where(
                                                                                                             "id",
                                                                                                             $params->id
                                                                                                         )->first();

        $cruiseCheckSelfListModel = CruiseCheckSelfDetailModel::query()
                                                              ->with([
                                                                  "cruiseOrderRel",
                                                                  "cruiseCheckDetailsRel"
                                                              ])
                                                              ->where("taskId", $params->id)
                                                              ->where("shopId", $params->shopId)
                                                              ->where("cruiseOrderId", ">", 0)
                                                              ->orderByDesc("id")
                                                              ->get();

        $executeStart    = str_replace(":", "", $selfCheckModel->executeStartHis);
        $executeEnd      = str_replace(":", "", $selfCheckModel->executeEndHis);
        $todayYmd        = date("Y-m-d", time());
        $nextYmd         = date("Y-m-d", strtotime("+1 day", time()));
        $startTimeSecond = strtotime($todayYmd . " {$selfCheckModel->executeStartHis}") - strtotime($todayYmd . " 00:00:00");
        if ($executeStart > $executeEnd) {
            //todo 执行周期隔天
            $endTimeSecond = strtotime($nextYmd . " {$selfCheckModel->executeEndHis}") - strtotime($todayYmd . " 00:00:00");
        } else {
            //todo 执行周期当天
            $endTimeSecond = strtotime($todayYmd . " {$selfCheckModel->executeEndHis}") - strtotime($todayYmd . " 00:00:00");
        }

        ShopSelfCheckDetailListResource::$executeStartSecond = $startTimeSecond;
        ShopSelfCheckDetailListResource::$executeEndSecond   = $endTimeSecond;
        $submitUserIds                                       = array_filter($cruiseCheckSelfListModel->pluck("cruiseCheckDetailsRel.createdByUid")
                                                                                                     ->toArray());
        if ($submitUserIds) {
            ShopSelfCheckDetailListResource::$userLists = array_column(
                (new RmsUserApi())->getUserInfoByIds($submitUserIds, ['id', 'username'])['data'] ?? [],
                'username',
                'id'
            );
        }

        return [
            "main" => ShopSelfCheckListResource::collection([$selfCheckModel])
                                               ->getIterator()->current(),
            "list" => ShopSelfCheckDetailListResource::collection($cruiseCheckSelfListModel)
        ];
    }

    /**
     * 作废任务
     *
     * @param object $params
     * @param int $uid
     * @throws \Exception
     */
    public static function invalidSingleTask(object $params, int $uid)
    {
        try {

            DB::beginTransaction();

            // todo 自检任务详情表作废
            CruiseCheckSelfDetailModel::query()->where("id", $params->id)->update(
                [
                    "status"       => CruiseCheckSelfDetailModel::STATUS_NOT_PRODUCE,
                    "createdAt"    => time(),
                    "updatedAt"    => time(),
                    "updatedByUid" => $uid
                ]
            );

            //作废订单
            CruiseOrderModel::query()
                            ->where('id', $params->cruiseOrderId)
                            ->update([
                                'status' => CruiseOrderModel::STATUS_CLOSED
                            ]);

            CruiseCheckDetailModel::query()
                                  ->where('orderId', $params->cruiseOrderId)
                                  ->update([
                                      'reportResult' => CruiseCheckDetailModel::REPORT_RESULT_CANCEL
                                  ]);

            // todo  cruise_check_details 更新当前操作用户uid
            CruiseCheckDetailModel::query()
                                  ->where('orderId', $params->cruiseOrderId)
                                  ->update([
                                      "submitTime"   => time(),
                                      "createdByUid" => $uid
                                  ]);

            //获得任务ID
            $taskId = (int)CruiseTaskOrderMappingModel::query()
                                                      ->where('orderId', $params->cruiseOrderId)
                                                      ->value('taskId');

            CruiseCheckTaskModel::query()
                                ->where('id', $taskId)
                                ->where('endTime', '<=', time()) // task仅在过期的时候，才会变作废
                                ->where('status', '!=', CruiseCheckTaskModel::STATUS_FINISH)
                                ->update([
                                    'status' => CruiseCheckTaskModel::STATUS_CANCEL
                                ]);

            DB::commit();
        } catch (\Exception $exception) {
            DB::rollBack();
            throw new \Exception();
        }
    }

    /**
     * 自检任务列表
     *
     * @param object $params
     * @return array
     */
    public static function shopSelfCheckTaskListV2(object $params): array
    {
        $CruiseCheckSelfTaskModel = CruiseCheckSelfTaskModel::query()
                                                            ->where("templateType", CruiseTemplateModel::TYPE_8)
//                                                            ->where("status", CruiseCheckSelfTaskModel::STATUS_ON)
                                                            ->where("taskStartTime", "<", time())
                                                            ->where("taskEndTime", ">", time())
                                                            ->where(function ($query) use ($params) {
                                                                $query->where("shopScope",
                                                                    CruiseCheckSelfTaskModel::SHOP_SCOPE_ALL)
                                                                      ->orWhereHas("cruiseCheckSelfTaskCompanyMappingsRel",
                                                                          function ($query) use ($params) {
                                                                              $query->where("shopId", $params->shopId);
                                                                          });
                                                            })
                                                            ->whereHas("cruiseCheckSelfDetailRel",
                                                                function ($query) use ($params) {
                                                                    $query->where("shopId", $params->shopId);
                                                                })
                                                            ->select(["id", "name", "rule", "status", "sysTemplate"])
                                                            ->get();


        $list = $CruiseCheckSelfTaskModel->map(function (CruiseCheckSelfTaskModel $cruiseCheckSelfTaskModel) use (
            $params
        ) {
            $cruiseCheckSelfTaskModel->sysTemplateText = CruiseTemplateModel::SYS_TEMPLATE_TEXT[$cruiseCheckSelfTaskModel->sysTemplate] ?? "";
            $cruiseCheckSelfTaskModel->ruleText        = CruiseCheckSelfTaskModel::RULE_TEXT[$cruiseCheckSelfTaskModel->rule] ?? "";
            $cruiseCheckSelfTaskModel->load([
                "cruiseCheckSelfDetailRel" => function ($query) use ($params) {
                    $query->where("shopId", $params->shopId)->select([
                            "id",
                            "shopId",
                            "taskId",
                            "date",
                            "cruiseOrderId",
                            "checkDetailsId",
                            "executeStartTime",
                            "executeEndTime",
                            "status",
                            "createdAt",
                            "submitTime",
                            "submitUsername"
                        ])->latest()->take(2);
                }
            ]);

            if ($cruiseCheckSelfTaskModel->cruiseCheckSelfDetailRel->count() == 1) {
                $cruiseCheckSelfDetail = $cruiseCheckSelfTaskModel->cruiseCheckSelfDetailRel->first();
            } else {
                $last = $cruiseCheckSelfTaskModel->cruiseCheckSelfDetailRel->last();
                if (
                    $last->status == CruiseCheckSelfDetailModel::STATUS_WAIT
                    &&
                    $last->executeEndTime > time()
                ) {
                    $cruiseCheckSelfDetail = $last;
                } else {
                    $cruiseCheckSelfDetail = $cruiseCheckSelfTaskModel->cruiseCheckSelfDetailRel->first();
                }
            }

            // 处理时间
            $cruiseCheckSelfDetail->dateDesc = $cruiseCheckSelfDetail->getExecuteDateText($cruiseCheckSelfTaskModel->rule);
            // 处理状态
            $cruiseCheckSelfDetail->generateCustomState();
            // 格式化时间
            $cruiseCheckSelfDetail->formatExecuteTime();

            $cruiseCheckSelfTaskModel->unsetRelation("cruiseCheckSelfDetailRel");
            $cruiseCheckSelfTaskModel->cruiseCheckSelfDetail = $cruiseCheckSelfDetail->only([
                "id",
                "shopId",
                "taskId",
                "date",
                "cruiseOrderId",
                "checkDetailsId",
                "executeStartTime",
                "executeEndTime",
                "submitTime",
                "submitUsername",
                "dateDesc",
                "customState",
                "customStateSort",
                "customStateText",
                "executeStartTimeText",
                "executeEndTimeText",
            ]);

            return $cruiseCheckSelfTaskModel;
        })->sortBy(function ($item) {
            return [$item["cruiseCheckSelfDetail"]["customStateSort"], $item["sysTemplate"]];
        })->values();

        return [
            "list" => $list->toArray()
        ];
    }
}
